#!/usr/bin/env python
# -*- coding:utf-8 -*-

'''
    文件助手
    版本历史:
        姚彧 2017-01-02 生成
        姚彧 2017-01-03 大文件使用遍历的方式读取
        姚彧 2017-01-12 目录遍历访问文件
        姚彧 2017-10-28 读取文件部分内容
        2018-11-03 打开文件读取数据的警告处理
'''

__all__ = ['CODING', 'yy_file_read_bytes', 'yy_file_read_content', 'yy_file_write_bytes', 'yy_file_write_content', 'yy_file_visit_lines',
           'yy_visit_dir_files',
           'yy_file_read_nbytes',
           'find_files',
           ]

import os
CODING = 'UTF8'

#------------------------------------------
#2017-10-28 读取文件部分内容
def yy_file_read_nbytes(filename, n):
    assert n > 0
    assert(os.path.isfile(filename)), filename
    return open(filename, 'rb').read(n)
#2017-10-28 读取文件部分内容
#------------------------------------------

def yy_file_read_bytes(filename):
    assert(os.path.isfile(filename)), filename
    # ResourceWarning: unclosed file <_io.BufferedReader name='points.txt'> return open(filename, 'rb').read()
    fp = open(filename, 'rb')
    data = fp.read()
    fp.close()
    return data

def yy_file_read_content(filename, coding=CODING):
    assert(os.path.isfile(filename)), filename
    data = yy_file_read_bytes(filename)
    return data.decode(coding)

def yy_file_write_bytes(filename, data):
    fp = open(filename, 'wb')
    fp.write(data)
    fp.close()

def yy_file_write_content(filename, content, coding=CODING):
    yy_file_write_bytes(filename, content.encode(coding))


#------------------------------------------
#2017-01-03 大文件使用遍历的方式读取
def _read_line(fp):
    line = fp.readline()
    if isinstance(line, str):
        return line
    elif isinstance(line, bytes):
        try:
            return line.decode().rstrip()
        except:
            return line.decode('gbk').rstrip()
    return line

def yy_file_visit_lines(filename, visitor, mode = 'r'):
    assert(os.path.isfile(filename)), filename
    fp = open(filename, mode)
    line = _read_line(fp)
    while line:
        if visitor(line):
            break
        line = _read_line(fp)
    fp.close()

#2017-01-03 大文件使用遍历的方式读取
#------------------------------------------


#------------------------------------------
#2017-01-12 目录遍历访问文件
def yy_visit_dir_files(rootdir, visitor, visit_child = True):
    for item in os.listdir(rootdir):
        item = os.path.join(rootdir, item)
        if os.path.isfile(item):
            if visitor(item):
                return True
        elif visit_child and os.path.isdir(item):
            if yy_visit_dir_files(item, visitor, visit_child):
                return True
#2017-01-12 目录遍历访问文件
#------------------------------------------


#------------------------------------------
#2017-11-03 查找文件
def find_files(basedir, functor = None) -> [str]:
    if not functor:
        functor = lambda x: True
    res = []
    for item in os.listdir(basedir):
        if functor(item):
            res.append(os.path.join(basedir, item))
    return res

#2017-11-03 查找文件
#------------------------------------------


if __name__ == '__main__':
    def dump(line):
        print(line.strip())

    #filename = r'F:\Other\3d\export\170103.osg'
    #yy_file_visit_lines(filename, dump)
    yy_visit_dir_files(r'E:\Temp', dump)